﻿using LCA.Community.DAL;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using LCA.Community.DAL.Model;
using LCA.Community.DAL.Interfaces;
using Microsoft.Practices.Unity;
using LCA.Community.DAL.Test.ModelFactories;
using System.Collections.Generic;

namespace LCA.Community.DAL.Test
{
    /// <summary>
    ///This is a test class for FriendshipsRepositoryTest and is intended
    ///to contain all FriendshipsRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class FriendshipsRepositoryTest : BaseTestClass
    {
        private UsersFactory _usersFactory = new UsersFactory();
        private FriendshipsFactory _friendshipFactory = new FriendshipsFactory();
        private List<User> _users;
        private List<Friendship> _friendships;

        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize()]
        public void InitializeTest()
        {
            UnityContainerInitializer();

            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            _users = _usersFactory.CreateList(10);
            _users.ForEach(u => usersRepository.Add(u));

            var friendshipsRepository = _unityContainer.Resolve<IFriendshipsRepository>();
            _friendships = new List<Friendship>();

            var friendship = _friendshipFactory.CreateEntiry(_users[0].RowKey, _users[1].RowKey);
            _friendships.Add(friendship);
            friendshipsRepository.Add(friendship);

            friendship = _friendshipFactory.CreateEntiry(_users[0].RowKey, _users[2].RowKey);
            _friendships.Add(friendship);
            friendshipsRepository.Add(friendship);

            friendship = _friendshipFactory.CreateEntiry(_users[0].RowKey, _users[3].RowKey);
            _friendships.Add(friendship);
            friendshipsRepository.Add(friendship);

            friendship = _friendshipFactory.CreateEntiry(_users[0].RowKey, _users[4].RowKey);
            _friendships.Add(friendship);
            friendshipsRepository.Add(friendship);

            friendship = _friendshipFactory.CreateEntiry(_users[0].RowKey, _users[5].RowKey);
            _friendships.Add(friendship);
            friendshipsRepository.Add(friendship);
        }

        /// <summary>
        /// Cleans up the test.
        /// </summary>
        [TestCleanup()]
        public void CleanupTest()
        {
            var usersRepository = _unityContainer.Resolve<UsersRepository>();
            var friendshipsRepository = _unityContainer.Resolve<IFriendshipsRepository>();
            usersRepository.DeleteTestEntities();
            friendshipsRepository.DeleteTestEntities();
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID1 = _users[0].RowKey;
            string userID2 = _users[7].RowKey; 

            target.Add(userID1, userID2);
            var friendship = target.Get(userID1, userID2);
            Assert.IsNotNull(friendship);

            friendship = target.Get(userID2, userID1);
            Assert.IsNotNull(friendship);
        }

        /// <summary>
        ///A test for AreFriends
        ///</summary>
        [TestMethod()]
        public void AreFriendsTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID1 = _users[0].RowKey;
            string userID2 = _users[1].RowKey;

            bool actual;
            actual = target.AreFriends(userID1, userID2);
            Assert.IsTrue(actual);

            userID1 = _users[1].RowKey;
            userID2 = _users[2].RowKey;

            actual = target.AreFriends(userID1, userID2);
            Assert.IsFalse(actual);
        }

        /// <summary>
        ///A test for Delete
        ///</summary>
        [TestMethod()]
        public void DeleteTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID1 = _users[0].RowKey;
            string userID2 = _users[1].RowKey;

            target.Delete(userID1, userID2);
            var actual = target.Get(userID1, userID2);
            Assert.IsNull(actual);
            actual = target.Get(userID2, userID1);
            Assert.IsNull(actual);
        }

        /// <summary>
        ///A test for Get
        ///</summary>
        [TestMethod()]
        public void GetTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID1 = _users[0].RowKey;
            string userID2 = _users[1].RowKey;

            Friendship actual;
            actual = target.Get(userID1, userID2);
            Assert.IsNotNull(actual);

            userID1 = _users[1].RowKey;
            actual = target.Get(userID1, userID2);
            Assert.IsNull(actual);
        }

        /// <summary>
        ///A test for DeleteAllUserFriendShips
        ///</summary>
        [TestMethod()]
        public void DeleteAllUserFriendShipsTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID = _users[0].RowKey;

            target.DeleteAllUserFriendShips(userID);
            var actual = target.GetFriendshipsByUser(userID);
            CollectionAssert.AreEquivalent(new List<IFriendshipsRepository>(), actual);
        }

        /// <summary>
        ///A test for GetFriendshipsByUser
        ///</summary>
        [TestMethod()]
        public void GetFriendshipsByUserTest()
        {
            var target = _unityContainer.Resolve<IFriendshipsRepository>();
            string userID = _users[0].RowKey;
            List<Friendship> expected = _friendships;

            List<Friendship> actual;
            actual = target.GetFriendshipsByUser(userID);

            CollectionAssert.AreEquivalent(expected, actual);
        }
    }
}
